import { isEmpty } from "@/utils/check"
import { getUrlParams } from "@/utils/utils"

// 需要缓存的key
const localCacheNames = ["location", "cityCode", "cityName", "cityRecord"]
const sessionCacheNames = ["urlCityCode", "userCityCode", "userCityName"]

export default {
  state: {
    cityCode: "", // 城市code
    cityName: "", // 城市名称
    cityRecord: [], // 城市历史纪录
    location: {}, // 定位信息
    urlCityCode: "", // URL城市code
    userCityCode: "", // 用户选择的城市code
    userCityName: "", // 用户选择的城市名称
    cityList: [] // 城市列表
  },
  getters: {
    location: (state) => state.location,
    cityCode: (state) => state.cityCode,
    cityName: (state) => state.cityName,
    cityRecord: (state) => state.cityRecord,
    urlCityCode: (state) => state.urlCityCode,
    userCityCode: (state) => state.userCityCode,
    userCityName: (state) => state.userCityName,
    cityList: (state) => state.cityList
  },
  mutations: {
    // 自动初始化
    INIT(state) {
      // 初始化本地缓存
      localCacheNames.forEach((name) => {
        let data = uni.getStorageSync(name)
        if (data) state[name] = data
      })

      // #ifdef WEB
      sessionCacheNames.forEach((name) => {
        let data = window.sessionStorage.getItem(name)
        if (data) {
          try {
            state[name] = JSON.parse(data)
          } catch (error) {
            state[name] = data
          }
        }
      })
      // #endif
    },

    // 设置城市
    SET_CITY(state, city = {}) {
      state.cityCode = city.cityCode
      state.cityName = city.cityName
      uni.setStorageSync("cityCode", city.cityCode)
      uni.setStorageSync("cityName", city.cityName)

      const index = state.cityRecord.findIndex((item) => item.cityCode === city.cityCode)
      if (index >= 0) {
        state.cityRecord.splice(index, 1, city)
      } else {
        state.cityRecord.push(city)
      }
      uni.setStorageSync("cityRecord", state.cityRecord)
    },

    // 设置城市code
    SET_CITY_CODE(state, data) {
      if (data) {
        state.cityCode = String(data)
        uni.setStorageSync("cityCode", data)
      }
    },

    // 设置城市名称
    SET_CITY_NAME(state, data) {
      state.cityName = data
      uni.setStorageSync("cityName", data)
    },

    // 设置定位信息
    SET_LOCATION(state, data) {
      state.location = data
      uni.setStorageSync("location", data)
    },

    // 设置城市历史纪录
    SET_CITY_RECORD(state, data) {
      const index = state.cityRecord.findIndex((item) => item.cityCode === data.cityCode)
      if (index >= 0) {
        state.cityRecord.splice(index, 1, data)
      } else {
        state.cityRecord.unshift(data)
      }
      state.cityRecord = state.cityRecord.slice(0, 12)

      uni.setStorageSync("cityRecord", state.cityRecord)
    },

    // 设置用户选择的城市信息
    SET_USER_CITY_INFO(state, data = {}) {
      // code
      if (data.cityCode) {
        state.userCityCode = data.cityCode
        // #ifdef WEB
        window.sessionStorage.setItem("userCityCode", data.cityCode)
        // #endif
      }
      // name
      if (data.cityName) {
        state.userCityName = data.cityName
        // #ifdef WEB
        window.sessionStorage.setItem("userCityName", data.cityName)
        // #endif
      }
    },

    // 设置URL城市code
    SET_URL_CITY_CODE(state, data) {
      if (data) {
        state.urlCityCode = String(data)
        // #ifdef WEB
        window.sessionStorage.setItem("urlCityCode", data)
        // #endif
      }
    },

    // 设置城市列表
    SET_CITY_LIST(state, data) {
      state.cityList = data
    }
  },
  actions: {
    // 自动初始化
    init({ state, commit }) {
      const { cityCode } = getUrlParams()
      if (cityCode) commit("SET_URL_CITY_CODE", cityCode)
      // 用户设置的城市信息
      if (state.userCityCode) {
        commit("SET_CITY_CODE", state.userCityCode)
        commit("SET_CITY_NAME", state.userCityName)
      } else if (state.urlCityCode) {
        commit("SET_CITY_CODE", state.urlCityCode)
        commit("SET_CITY_NAME", "")
      }
    },

    // 初始化定位
    async initLocation({ state, commit, dispatch }) {
      setTimeout(async () => {
        const location = await dispatch("getLocation")
        // 用户选择城市优先级第一
        if (state.userCityCode) {
          commit("SET_CITY_CODE", state.userCityCode)
          commit("SET_CITY_NAME", state.userCityName)
        } else if (state.urlCityCode) {
          commit("SET_CITY_CODE", state.urlCityCode)
          const find = (state.cityList || []).find((item) => item.cityId == state.urlCityCode)
          if (find) {
            commit("SET_CITY_NAME", find.regionName)
          } else {
            commit("SET_CITY_CODE", location.cityCode)
            commit("SET_CITY_NAME", location.cityName)
          }
        } else {
          commit("SET_CITY_NAME", location.cityName)
          commit("SET_CITY_CODE", location.cityCode)
        }
      }, 500)
    },

    // 获取城市列表
    getCityList({ state, commit }) {
      return new Promise(async (resolve, reject) => {
        try {
          const res = await uni.$api.cinema.cityList({}, { queue: "sync" })
          commit("SET_CITY_LIST", res || [])
          if (state.urlCityCode) {
            const find = (res || []).find((item) => item.cityId == state.cityCode)
            if (find) {
              commit("SET_CITY_CODE", find.cityId)
              commit("SET_CITY_NAME", find.regionName)
            }
          }
          resolve()
        } catch (error) {
          reject(error)
        }
      })
    },

    // 获取定位信息
    getLocation({ commit }) {
      return new Promise(async (resolve, reject) => {
        try {
          let location = {}

          // #ifdef WEB
          // 判断是否需要定位
          const urlParams = uni.$getUrlParams()
          if (urlParams.noGetLocation && isEmpty(urlParams.forceGetLocation)) {
            return reject("URL存在禁止定位参数，已取消定位")
          }

          const sdk = uni.$auth?.sdk
          if (sdk) {
            sdk.onReady(async () => {
              if (sdk.checkApi("getLocation")) {
                // 超时容错处理
                const timer = setTimeout(async () => {
                  console.log("SDK定位超时")
                  location = await uni.$getLocation()
                  commit("SET_LOCATION", location)
                  resolve(location)
                }, 3000)
                console.log("开始SDK定位")
                const sdkRes = await uni.$auth.sdk.getLocation()
                console.log("SDK定位成功")
                clearTimeout(timer)
                console.log("开始定位解析")
                location = await uni.$api.public.getLocation({ lng: sdkRes.longitude, lat: sdkRes.latitude, type: sdkRes.type || "gcj02" })
                console.log("定位解析成功", location)
                commit("SET_LOCATION", location)
                resolve(location)
              } else {
                location = await uni.$getLocation()
                commit("SET_LOCATION", location)
                resolve(location)
              }
            })
          } else {
            location = await uni.$getLocation()
            commit("SET_LOCATION", location)
            resolve(location)
          }
          // #endif

          // 除WEB以外的平台
          // #ifndef WEB
          location = await uni.$getLocation()
          commit("SET_LOCATION", location)
          resolve(location)
          // #endif
        } catch (error) {
          reject(error)
        }
      })
    }
  }
}
